<script setup lang="ts">
import { addPrivateApi, addPublicApi, getApiInfoList, type ApiInfo } from '@/api/app-list/app-list'
import { useRenderIcon } from '@/components/ReIcon/src/hooks'
import { validateFileUploaded } from '@/components/upload-file/validator'
import { usePagination } from '@/hooks/usePagination'
import useTableRowSelection from '@/hooks/useTableRowSelection'
import useDictStore from '@/store/modules/dict'
import { ModalShowType, ModalShowTitle } from '@/types/common'
import { getToken } from '@/utils/auth'
import { omitEmptyValue } from '@/utils/common'
import { message } from '@/utils/message'
import Search from '@iconify-icons/ep/search'
import dayjs from 'dayjs'
import {
  ElButton,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElSelect,
  FormInstance,
} from 'element-plus'
import { isNil } from 'lodash-es'
import { computed, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { FormRules } from 'element-plus'

const route = useRoute()
const router = useRouter()
const props = defineProps<{
  modalShow: ModalShowType
  apiType: 'private' | 'public'
  termId: string
  apiIds?: string[]
}>()

const emit = defineEmits<{
  'update:modalShow': [ModalShowType]
  search: []
}>()

const modalShow = computed({
  get() {
    return props.modalShow
  },
  set(value) {
    emit('update:modalShow', value)
  },
})
const ruleFormRef = ref<FormInstance>()
const dictStore = useDictStore()
const { api_type } = dictStore.getDicts('api_type')

const queryParams = ref({
  apiName: '',
  apiType: '',
  enabledStatus: '1',
  isMine: false,
})

const loading = ref(false)

const { pagination, paginationParams, changePageNumber, changePageSize } = usePagination(onSearch)

const dataList = ref([])

async function onSearch() {
  loading.value = true
  if (props.apiType === 'private') {
    queryParams.value.isMine = true
  } else {
    queryParams.value.isMine = false
  }
  if (!queryParams.value.apiType) {
    queryParams.value.apiType = ''
  }
  const { rows, total } = await getApiInfoList({
    isMine: queryParams.value.isMine,
    ...omitEmptyValue({
      enabledStatus: queryParams.value.enabledStatus,
      apiName: queryParams.value.apiName,
      apiType:
        props.apiType === 'private'
          ? '3'
          : queryParams.value.apiType == ''
            ? '1,2'
            : queryParams.value.apiType,
      ...paginationParams.value,
    }),
  }).finally(() => {
    loading.value = false
  })
  dataList.value = rows
  pagination.total = total
}

const { selectedRows, onRowSelectionChange } = useTableRowSelection<ApiInfo>()
const approvalRequired = computed(
  () => selectedRows.value.find((row) => api_type.getLabel(row.apiType) === '需审批') !== undefined
)

const columns: TableColumnList = [
  {
    type: 'selection',
    width: 55,
    align: 'left',
  },
  {
    label: '接口名称',
    prop: 'apiName',
    minWidth: 100,
  },
  {
    label: '接口类型',
    prop: 'apiType',
    minWidth: 100,
    formatter({ apiType }) {
      return api_type.getLabel(apiType)
    },
  },
  {
    label: '接口描述',
    prop: 'apiDesc',
    minWidth: 100,
  },
  {
    label: '操作',
    fixed: 'right',
    width: 180,
    slot: 'operation',
  },
]

const formData = ref({
  // appId: props.termId,
  applyDept: '',
  applyPerson: '',
  applyPhone: '',
  applyAddr: '',
  applyEmail: '',
  applyUseScene: '',
  searchDateRange: [dayjs(new Date()).format('YYYY/MM/DD'), dayjs(new Date()).format('YYYY/MM/DD')],
  applyAnnex: '',
})

const isFinished = ref(true)

const rules = ref<FormRules>({
  applyDept: [{ required: true, message: '请输入' }],
  applyPerson: [{ required: true, message: '请输入' }],
  applyPhone: [
    {
      required: true,
      message: '请输入',
      trigger: 'blur',
    },
    {
      pattern: /^((0\d{2,3}-\d{7,8})|(1[345678]\d{9}))$/,
      message: '请输入固话或手机号',
      trigger: ['blur', 'change'],
    },
  ],
  applyAddr: [{ required: true, message: '请选择' }],
  applyEmail: [
    { required: true, message: '请输入' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] },
    {
      min: 6,
      max: 50,
      message: '长度在 6 到 50 个字符',
      trigger: 'blur',
    },
  ],
  searchDateRange: [{ required: true, message: '请输入' }],
  applyAnnex: [
    validateFileUploaded(isFinished),
    { required: true, message: '必填', trigger: 'change' },
  ],
  applyUseScene: [{ required: true, message: '请输入' }],
})

const searchDateRangeParams = computed(() =>
  !isNil(formData.value.searchDateRange)
    ? {
        applyUseTimeBegin: dayjs(formData.value.searchDateRange[0], 'YYYY/MM/DD').format(
          'YYYY-MM-DD HH:mm:ss'
        ),
        applyUseTimeEnd: dayjs(formData.value.searchDateRange[1], 'YYYY/MM/DD').format(
          'YYYY-MM-DD HH:mm:ss'
        ),
      }
    : null
)

const submitForm = async (formEl: FormInstance | undefined) => {
  let uniqueAppApiBoList = []
  if (props.apiIds) {
    const ids = new Set(props.apiIds)
    uniqueAppApiBoList = selectedRows.value
      .filter((v) => {
        if (!ids.has(v.id)) return true
        else {
          message('接口：' + v.apiName + '已添加，不再重复添加', { type: 'warning' })
          return false
        }
      })
      .map((v) => ({
        id: v.id,
        appId: route.query.id,
        apiId: v.id,
        apiType: v.apiType,
        apiName: v.apiName,
      }))
    if (uniqueAppApiBoList.length == 0) {
      return
    }
  } else {
    uniqueAppApiBoList = selectedRows.value.map((v) => ({
      id: v.id,
      appId: route.query.id,
      apiId: v.id,
      apiType: v.apiType,
      apiName: v.apiName,
    }))
  }
  if (props.apiType === 'private') {
    await addPrivateApi({
      appApiBoList: uniqueAppApiBoList,
    })
    message('提交成功', { type: 'success' })
    resetFields()
    modalShow.value = ModalShowType.Hide
    emit('search')
  } else {
    if (approvalRequired.value) {
      if (!formEl) return
      await formEl.validate(async (valid) => {
        if (valid) {
          if (props.apiType === 'public') {
            await addPublicApi({
              appApiBoList: uniqueAppApiBoList,
              applyInfoBo: {
                appId: props.termId,
                ...formData.value,
                ...searchDateRangeParams.value,
              },
            })
            message('提交成功', { type: 'success' })
            resetFields()
            modalShow.value = ModalShowType.Hide
            emit('search')
          }
        } else {
          message('请确认下方的申请单填写完毕', { type: 'warning' })
        }
      })
    } else {
      await addPublicApi({
        appApiBoList: uniqueAppApiBoList,
      })
      message('提交成功', { type: 'success' })
      resetFields()
      modalShow.value = ModalShowType.Hide
      emit('search')
    }
  }
}

const resetFields = () => {
  formData.value = {
    applyDept: '',
    applyPerson: '',
    applyPhone: '',
    applyAddr: '',
    applyEmail: '',
    applyUseScene: '',
    searchDateRange: [
      dayjs(new Date()).format('YYYY/MM/DD'),
      dayjs(new Date()).format('YYYY/MM/DD'),
    ],
    applyAnnex: '',
  }
}
const onOpen = async () => {
  resetFields()
  await onSearch()
}

const beforeCloseDialog = () => {
  onClose()
}

const onClose = () => {
  modalShow.value = ModalShowType.Hide
  resetFields()
}

const disabledDate = (time: Date) => {
  return time.getTime() < Date.now() - 24 * 60 * 60 * 1000
}
</script>

<template>
  <el-drawer
    :close-on-click-modal="false"
    :title="ModalShowTitle.get(modalShow) + '接口'"
    class="common-dialog"
    :model-value="modalShow !== ModalShowType.Hide"
    :before-close="beforeCloseDialog"
    size="50%"
    @open="onOpen"
  >
    <el-form
      element-loading-text="正在获取接口列表..."
      :model="queryParams"
      :disabled="props.modalShow === ModalShowType.View"
    >
      <el-row :gutter="10">
        <el-col :span="12">
          <el-form-item>
            <el-input v-model="queryParams.apiName" placeholder="请输入接口名称" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item v-if="props.apiType === 'public'">
            <el-select v-model="queryParams.apiType" placeholder="请选择接口分类" clearable>
              <el-option key="2" label="需审批" value="2" />
              <el-option key="1" label="免审批" value="1" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="4">
          <el-form-item>
            <el-button
              type="primary"
              :icon="useRenderIcon(Search)"
              :loading="loading"
              @click="onSearch()"
            >
              查询
            </el-button>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <pure-table
      border
      align-whole="center"
      showOverflowTooltip
      table-layout="auto"
      :loading="loading"
      :data="dataList"
      :columns="columns"
      :header-cell-style="{
        background: 'var(--el-table-row-hover-bg-color)',
        color: 'var(--el-text-color-primary)',
      }"
      :pagination="pagination"
      @page-size-change="changePageSize"
      @page-current-change="changePageNumber"
      @selection-change="onRowSelectionChange"
    >
      <template #operation="{ row }">
        <el-button
          link
          type="primary"
          @click="
            router.push({
              path: '/api-manage/detail',
              query: { id: row.id },
            })
          "
        >
          接口详情</el-button
        >
      </template>
    </pure-table>
    <section-info v-if="approvalRequired && props.apiType === 'public'">
      <template #title>申请单填写</template>
      <el-form
        ref="ruleFormRef"
        :model="formData"
        :rules="approvalRequired ? rules : null"
        label-width="80"
      >
        <el-form-item label="申请单位" prop="applyDept">
          <el-input
            v-model="formData.applyDept"
            placeholder="请输入"
            show-word-limit
            :maxlength="50"
        /></el-form-item>
        <el-form-item label="申请人" prop="applyPerson">
          <el-input
            v-model="formData.applyPerson"
            placeholder="请输入"
            show-word-limit
            :maxlength="20"
          />
        </el-form-item>
        <el-form-item label="联系电话" prop="applyPhone">
          <el-input v-model="formData.applyPhone" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="联系地址" prop="applyAddr">
          <el-input
            v-model="formData.applyAddr"
            placeholder="请输入"
            show-word-limit
            :maxlength="100"
          />
        </el-form-item>
        <el-form-item label="联系邮箱" prop="applyEmail">
          <el-input v-model="formData.applyEmail" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="使用场景" prop="applyUseScene">
          <el-input
            v-model="formData.applyUseScene"
            type="textarea"
            placeholder="输入内容"
            maxlength="300"
            show-word-limit
            :rows="4"
          />
        </el-form-item>
        <el-form-item label="使用时间" prop="searchDateRange">
          <el-date-picker
            v-model="formData.searchDateRange"
            unlink-panels
            type="daterange"
            value-format="YYYY/MM/DD"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :disabled-date="disabledDate"
          />
        </el-form-item>
        <el-form-item label="文件上传" prop="applyAnnex">
          <UploadFile
            v-model:file-ids="formData.applyAnnex"
            v-model:finished="isFinished"
            :suffix="['.doc', '.docx', '.pdf', '.jpg', '.jpeg', '.png']"
            :accept="'.doc,.docx,.pdf,.jpg,.jpeg,.png'"
            :limit="20"
            :max="100"
          />
        </el-form-item>
      </el-form>
    </section-info>
    <template #footer>
      <template v-if="modalShow !== ModalShowType.View">
        <el-button @click="beforeCloseDialog">取消</el-button>
        <el-button
          type="primary"
          :disabled="selectedRows.length === 0"
          @click="submitForm(ruleFormRef)"
        >
          提交
        </el-button>
      </template>
      <el-button v-if="modalShow === ModalShowType.View" @click="modalShow = ModalShowType.Hide">
        关闭
      </el-button>
    </template>
  </el-drawer>
</template>
